﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;


//class Person
//{
//public:
//	void Print()
//	{
//		cout << "name:" << _name << endl;
//		cout << "age:" << _age << endl;
//	}
////protected: //在子类可见(不能用)   只能防外面
//private: //在子类不可见(不能用) 不仅防外面，还防儿子
//	string _name = "peter"; 
//	int _age = 18; 
//};
//// 继承后父类的Person的成员（成员函数+成员变量）都会变成子类的一部分。这里体现出了
////Student和Teacher复用了Person的成员。可以看到变量的复用。调用Print可以看到成员函数的复用。
//class Student : public Person
//{
//public:
//	void func()
//	{
//		//cout << _name << endl;
//		cout << "void func()" << endl;
//	}
//protected:
//	int _stuid; 
//};
//
////这里不写访问限定符也可以，class的默认访问限定符是private，struct的默认访问限定符是public
////class Teacher : Person //因为Teacher是私有的,所以不能访问父类的共有成员Print,私有不能访问公有
//class Teacher : public Person
//{
//protected:
//	int _jobid; 
//};
//
//
//int main()
//{
//	//Student s;
//	//Teacher t;
//	//s.Print();
//	//t.Print();
//	//void func();
//
//	double d = 1.1;
//	int i = d; //隐式类型转换，会产生一个临时变量，
//	const int& ri = d; //此时引用的是d转换成int产生的临时变量，临时变量具有常性不能修改，所以这里加一个const
//
//	//子给父，基类和派生类对象赋值转换
//	Student s; //在共有基类中，子类就是一个特殊的父类
//	Person p = s; //天然支持的转换，不存在类型转换的发生
//	Person& rp = s; //中间没有产生临时变量
//	Person* ptrp = &s;
//
//
//	return 0;
//}

//class Person
//{
//public:
//	void Print()
//	{
//		cout << "name:" << _name << endl;
//		cout << "age:" << _age << endl;
//		cout << "num:" << _num << endl;
//	}
//protected: //在子类可见(不能用)   只能防外面
////private: //在子类不可见(不能用) 不仅防外面，还防儿子
//	string _name = "yxj";
//	int _age = 18;
//	int _num = 222;
//};
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << Person::_num << endl;
//		cout << _num << endl;
//	}
//protected:
//	int _stuid = 2021;
//	int _num = 111;
//};
//
//int main()
//{
//	Student s;
//	s.Print();
//
//	return 0;
//}

// B中的fun和A中的fun不是构成重载，因为不是在同一作用域
// B中的fun和A中的fun构成隐藏，成员函数满足函数名相同就构成隐藏。
//class A
//{
//public:
//	void fun()
//	{
//		cout << "func()" << endl;
//	}
//};
//class B : public A
//{
//public:
//	void fun(int i)
//	{
//		A::fun();
//		cout << "func(int i)->" << i << endl;
//	}
//};
//
////A:两个fun构成函数重载
////B:两个fun构成隐藏√
////C:编译报错
////D:以上说法都不对
//void Test()
//{
//	B b;
//	b.fun(10);
//
//	//B b;
//	b.A::fun();
//};
//
//
//int main()
//{
//	Test();
//	return 0;
//}


//class Person
//{
//public:
//	Person(const char* name = "peter")
//		: _name(name)
//	{
//		cout << "Person()" << endl;
//	}
//
//	Person(const Person& p)
//		: _name(p._name)
//	{
//		cout << "Person(const Person& p)" << endl;
//	}
//
//	Person& operator=(const Person & p)
//	{
//		cout << "Person operator=(const Person& p)" << endl;
//		if (this != &p)
//			_name = p._name;
//
//		return *this;
//	}
//
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//protected:
//	string _name; // 姓名
//};
//
////父类的成员变量必须调用父类的构造函数初始化
//class Student : public Person
//{
//public:
//	Student(const char* name,int num)
//		//:_name(name) //非法的成员初始化，_name是基类的成员
//		//显示初始化，不写也是可以编译通过的，父类定义了缺省的构造初始化函数 
//		:Person(name)
//		,_num(num)
//	{
//		cout << "Student()" << endl;
//	}
//	
//	//拷贝构造
//	Student(const Student& s)
//		:Person(s) //切割
//		,_num(s._num)
//	{
//		cout << "Student(const Student& s)" << endl;
//
//	}
//
//	Student& operator=(const Student& s)
//	{
//
//		if (this != &s)
//		{
//			Person::operator=(s);
//			_num = s._num;
//		}
//		cout << "Student& operator=(const Student& s)" << endl;
//		return *this;
//	}
//
//	//析构函数会被处理成destructor
//	//子类析构函数完成时，会自动调用父类析构函数，保证先析构子在析构父亲
//	~Student()
//	{
//		//~Person();
//		cout << "~Student()" << endl;
//	}
//protected:
//	int _num;
//};
//
//int main()
//{
//	Student s1("张三",18);
//	Student s2(s1);
//
//	Person p = s1; 
//	s1 = s2;
//	return 0;
//}

////友元关系不能继承，
//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//};
//class Student : public Person
//{
//	friend void Display(const Person& p, const Student& s);
//protected:
//	int _stuNum; // 学号
//};
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;
//}
//void main()
//{
//	Person p;
//	Student s;
//	Display(p, s);
//}


////继承与静态成员：静态成员不会被继承，静态成员只有一个，是所有的派生类共享 
//class Person
//{
//public:
//	Person() { ++_count; }
////protected:
//	string _name; // 姓名
//public:
//	static int _count; // 统计人的个数。
//};
//int Person::_count = 0;
//
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//
//class Graduate : public Student
//{
//protected:
//	string _seminarCourse; // 研究科目
//};
//
//int main()
//{
//	Person p;
//	Student s;
//	//cout << &(p._name) << endl;
//	//cout << &(s._name) << endl;
//
//	//cout << &(p._count) << endl;
//	//cout << &(s._count) << endl;
//
//	//计算Person以及以Person继承的子类对象总共创建的个数
//	Graduate g1;
//	Graduate g2;
//	cout << Person::_count << endl;
//	cout << Graduate::_count << endl;
//
//	return 0;
//}

//实现一个不能被继承的类:创建一个私有的构造函数或者析构函数(因为派生类构造函数必须先调用父类构造函数)
//class A
//{
//private:
//	A()
//	{}
//};
//
//class B : public A
//{};
//
//int main()
//{
//
//	//B bb;
//
//	return 0;
//}


//多继承的问题：可能会导致菱形继承，这样会有二义性无法明确知道访问的是哪一个，数据冗余
//解决办法：虚拟继承 virtual
//class Person
//{
//public: 
//	string _name; // 姓名
//};
//class Student : virtual public Person
//{
//protected:
//	int _num; //学号
//};
//class Teacher : virtual public Person
//{
//protected:
//	int _id; // 职工编号
//};
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//};
//void Test()
//{
//	// 这样会有二义性无法明确知道访问的是哪一个
//	Assistant a;
//	a._name = "peter";
//	// 需要显示指定访问哪个父类的成员可以解决二义性问题，但是数据冗余问题无法解决
//	a.Student::_name = "xxx";
//	a.Teacher::_name = "yyy";
//}

//class A
//{
//public:
//	int _a;
//};
//class B : public A
////class B : virtual public A
//{
//public:
//	int _b;
//};
//class C : public A
////class C : virtual public A
//{
//public:
//	int _c;
//};
//class D : public B, public C
//{
//public:
//	int _d;
//};
//int main()
//{
//	D d;
//	d.B::_a = 1;
//	d.C::_a = 2;
//	d._b = 3;
//	d._c = 4;
//	d._d = 5;
//	return 0;
//}


//公共继承  --- is-a，耦合度高(B可以直接用A的3个成员)
class A
{
public:
	void func(){}
protected:
	int _c1;
	int _c2;
};

//A改动保护可能会影响B
class B : public A
{};

//组合 --- has-a，耦合度低(B可以直接用A的一个成员，直接用另外两个成员)
class C
{
public:
	void func() {}
protected:
	int _c1;
	int _c2;
};
//C改动保护和私有成员基本不影响D
class D
{
private:
	C _cc;
};

int main()
{
	D d;
	return 0;
}